package com.tomorrow.runner.map;

import android.Manifest;
import android.annotation.TargetApi;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.widget.Toast;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationClient;
import com.amap.api.location.AMapLocationClientOption;
import com.amap.api.location.AMapLocationListener;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.SupportMapFragment;
import com.amap.api.maps2d.UiSettings;
import com.amap.api.maps2d.model.BitmapDescriptor;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.Marker;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.model.MyLocationStyle;
import com.amap.api.maps2d.model.PolylineOptions;
import com.tomorrow.runner.R;
import com.tomorrow.runner.util.Define;

import java.util.ArrayList;
import java.util.List;

import cn.sucun.android.log.Log;


public class MapFragment extends SupportMapFragment implements LocationSource,AMapLocationListener {

    public interface LocationListener{
        void onLocationSuccess(AMapLocation amapLocation);
        void onLocationLost(AMapLocation lastLocation);
    }


    public enum SetupModel{
        Location,
        ShowTrack
    }
    private static final String TAG = MapFragment.class.getName();
    private static final int PERMISSIONS_REQUEST_GPS = 1;
    private AMap mMap;
    private OnLocationChangedListener mListener;
    private AMapLocationClient mLocationClient;
    private AMapLocationClientOption mLocationOption;

    private LocationListener mLocationListener;
    public static final long FAST = 1000;
    public static final long NORMAL = 5000;
    public static final long SLOW = 10000;
    private long mLocationNotifyPeriod = NORMAL;
    private long mLastNotifyTime = -1;
    public void setLocationListener(LocationListener locationListener,long notifyPeriod) {
        this.mLocationListener = locationListener;
        this.mLocationNotifyPeriod = notifyPeriod;
    }
    public MapFragment(){

    }

    @Override
    public void onCreate(Bundle bundle) {
        super.onCreate(bundle);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
            checkGPSPermission();
        }
    }

    @TargetApi(Build.VERSION_CODES.M)
    private void checkGPSPermission() {
        if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    PERMISSIONS_REQUEST_GPS);
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (PERMISSIONS_REQUEST_GPS == requestCode && grantResults[0] == PackageManager.PERMISSION_GRANTED){
            setUpMapIfNeeded(SetupModel.Location,null);
        }
    }

    public void setUpMapIfNeeded(SetupModel setupModel,Bundle params) {
        if (mMap == null) {
            mMap = getMap();
        }
        setUpMap(setupModel,params);
    }
    /**
     * 设置一些amap的属性
     */
    private void setUpMap(SetupModel setupModel,Bundle params) {
        switch (setupModel){
            case Location:
                // 自定义系统定位小蓝点
                MyLocationStyle myLocationStyle = new MyLocationStyle();
                myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.mipmap.human));// 设置小蓝点的图标
                myLocationStyle.strokeColor(Color.BLACK);// 设置圆形的边框颜色
                myLocationStyle.radiusFillColor(Color.argb(128,135,206,235));// 设置圆形的填充颜色
                // myLocationStyle.anchor(int,int)//设置小蓝点的锚点
                myLocationStyle.strokeWidth(1.0f);// 设置圆形的边框粗细
                mMap.setMyLocationStyle(myLocationStyle);
                mMap.setLocationSource(this);// 设置定位监听
                UiSettings uiSettings = mMap.getUiSettings();
                uiSettings.setMyLocationButtonEnabled(true);// 设置默认定位按钮是否显示
                uiSettings.setCompassEnabled(true);//显示罗盘
                uiSettings.setScaleControlsEnabled(true);//比例尺是否显示
                uiSettings.setScrollGesturesEnabled(true);//启用缩放手势
                mMap.animateCamera(CameraUpdateFactory.zoomTo(Define.MAX_ZOOM_LEVEL - 2));
                mMap.setMyLocationEnabled(true);// 设置为true表示显示定位层并可触发定位，false表示隐藏定位层并不可触发定位，默认是false
                mMap.setTrafficEnabled(false);
                break;
            case ShowTrack:
                String dataText = params.getString(Define.KEY_DATA);
                if (TextUtils.isEmpty(dataText)){
                    return;
                }
                JSONArray points = JSON.parseArray(dataText);
                List<LatLng> pointList = new ArrayList<>();
                for (int i = 0;i<points.size();i++){
                    LatLngPoint point = points.getObject(i,LatLngPoint.class);
                    pointList.add(new LatLng(point.lat,point.lng));
                }
                if (pointList.size() > 0){
                    mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(pointList.get(0),Define.MAX_ZOOM_LEVEL - 3));
                }
                drawPolyline(pointList);
                break;
        }

    }

    /**
     * 激活定位
     */
    @Override
    public void activate(OnLocationChangedListener listener) {
        mListener = listener;
        if (mLocationClient == null) {
            mLocationClient = new AMapLocationClient(getActivity());
            mLocationOption = new AMapLocationClientOption();
            //设置定位监听
            mLocationClient.setLocationListener(this);
            //设置为高精度定位模式
            mLocationOption.setLocationMode(AMapLocationClientOption.AMapLocationMode.Hight_Accuracy);
            //设置定位参数
            mLocationClient.setLocationOption(mLocationOption);
            // 此方法为每隔固定时间会发起一次定位请求，为了减少电量消耗或网络流量消耗，
            // 注意设置合适的定位时间的间隔（最小间隔支持为2000ms），并且在合适时间调用stopLocation()方法来取消定位请求
            // 在定位结束后，在合适的生命周期调用onDestroy()方法
            // 在单次定位情况下，定位无论成功与否，都无需调用stopLocation()方法移除请求，定位sdk内部会移除
            mLocationClient.startLocation();
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        deactivate();
    }

    /**
     * 停止定位
     */
    @Override
    public void deactivate() {
        mListener = null;
        if (mLocationClient != null) {
            mLocationClient.stopLocation();
            mLocationClient.onDestroy();
        }
        mLocationClient = null;
    }
    int errorCode = 0;
    AMapLocation mAmapLocation;
    /**
     * 定位成功后回调函数
     */
    @Override
    public void onLocationChanged(AMapLocation amapLocation) {
        if (mListener != null && amapLocation != null) {
            if (amapLocation.getErrorCode() == 0) {
                mAmapLocation = amapLocation;
                if (mLocationListener != null){
                    if (mLastNotifyTime == -1){
                        mLastNotifyTime = System.currentTimeMillis();
                        mLocationListener.onLocationSuccess(mLocationClient.getLastKnownLocation());
                    }
                    else{
                        if ((System.currentTimeMillis() - mLastNotifyTime) >= mLocationNotifyPeriod){
                            mLastNotifyTime = System.currentTimeMillis();
                            mLocationListener.onLocationSuccess(mLocationClient.getLastKnownLocation());
                        }
                    }
                }
                mListener.onLocationChanged(amapLocation);// 显示系统小蓝点
//                double latitude = amapLocation.getLatitude();
//                double longitude = amapLocation.getLongitude();
//                String text = "latitude="+latitude+"  |  longitude="+longitude;
//                Log.i(TAG,text);
            } else {
                if (mLocationListener != null){
                    if (mLastNotifyTime == -1){
                        mLastNotifyTime = System.currentTimeMillis();
                        mLocationListener.onLocationLost(mLocationClient.getLastKnownLocation());
                    }
                    else{
                        if ((System.currentTimeMillis() - mLastNotifyTime) >= mLocationNotifyPeriod){
                            mLastNotifyTime = System.currentTimeMillis();
                            mLocationListener.onLocationLost(mLocationClient.getLastKnownLocation());
                        }
                    }
                }
                String errText = "定位失败," + amapLocation.getErrorCode()+ ": " + amapLocation.getErrorInfo();
                if (errorCode != amapLocation.getErrorCode()){
                    Toast.makeText(getActivity(),errText,Toast.LENGTH_SHORT).show();
                    errorCode = amapLocation.getErrorCode();
                }
                Log.e(TAG,errText);
            }
        }
    }


    public Marker addMark(int imageId, LatLng position){
        MarkerOptions markerOptions = new MarkerOptions();
        BitmapDescriptor bitmapDescriptor = BitmapDescriptorFactory.fromResource(imageId);
        markerOptions.icon(bitmapDescriptor);
        markerOptions.position(position);
        markerOptions.draggable(true);
        return mMap.addMarker(markerOptions);
    }


    private void drawPolyline(List<LatLng> points){
        PolylineOptions polylineOptions = new PolylineOptions();
        polylineOptions.addAll(points);
        mMap.addPolyline(polylineOptions);
    }

}
